// /*
// * Copyright 2025 the original author or authors.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * https://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
// package com.alibaba.cloud.ai.manus.tool.filesystem;

// import java.io.IOException;
// import java.nio.file.Files;
// import java.nio.file.Path;
// import java.util.ArrayList;
// import java.util.List;

// import org.slf4j.Logger;
// import org.slf4j.LoggerFactory;
// import org.springframework.context.ApplicationContext;

// import com.alibaba.cloud.ai.manus.tool.AbstractBaseTool;
// import com.alibaba.cloud.ai.manus.tool.code.ToolExecuteResult;
// import com.alibaba.cloud.ai.manus.tool.excelProcessor.ExcelProcessorTool;
// import com.alibaba.cloud.ai.manus.tool.excelProcessor.IExcelProcessingService;
// import com.alibaba.cloud.ai.manus.tool.innerStorage.SmartContentSavingService;
// import com.alibaba.cloud.ai.manus.tool.tableProcessor.TableProcessingService;
// import com.alibaba.cloud.ai.manus.tool.tableProcessor.TableProcessorTool;
// import com.alibaba.cloud.ai.manus.tool.textOperator.GlobalFileOperator;
// import com.alibaba.cloud.ai.manus.tool.textOperator.TextFileService;
// import com.fasterxml.jackson.annotation.JsonProperty;
// import com.fasterxml.jackson.databind.ObjectMapper;

// /**
// * Intelligent File Processing Tool - jmanus style: Simple, Direct, Smart
// *
// * True jmanus principles: 1. Tool is simple class with clear purpose 2. Tools create
// * other tools on demand (following existing pattern) 3. Smart function-based tool
// * selection (the real "function as first-class citizen") 4. Minimal dependencies,
// maximum
// * effectiveness
// */
// public class UploadedFileLoaderTool extends
// AbstractBaseTool<UploadedFileLoaderTool.UploadedFileInput> {

// private static final Logger log =
// LoggerFactory.getLogger(UploadedFileLoaderTool.class);

// private static final String TOOL_NAME = "uploaded_file_loader";

// // Simple jmanus dependencies
// private final UnifiedDirectoryManager directoryManager;

// private final ApplicationContext applicationContext;

// public UploadedFileLoaderTool(UnifiedDirectoryManager directoryManager,
// ApplicationContext applicationContext) {
// this.directoryManager = directoryManager;
// this.applicationContext = applicationContext;
// }

// /**
// * Input class for uploaded file operations
// */
// public static class UploadedFileInput {

// @JsonProperty("action")
// private String action;

// @JsonProperty("file_name")
// private String fileName;

// // Getters and setters
// public String getAction() {
// return action;
// }

// public void setAction(String action) {
// this.action = action;
// }

// public String getFileName() {
// return fileName;
// }

// public void setFileName(String fileName) {
// this.fileName = fileName;
// }

// }

// @Override
// public ToolExecuteResult run(UploadedFileInput input) {
// String action = input.getAction();
// log.info("UploadedFileLoaderTool action: {}", action);

// try {
// return switch (action.toLowerCase()) {
// case "list_files" -> listUploadedFiles();
// case "process_file" -> processFile(input);
// default -> new ToolExecuteResult(
// "Unsupported action: " + action + ". Supported actions: list_files, process_file");
// };
// }
// catch (Exception e) {
// log.error("Error executing UploadedFileLoaderTool action: {}", action, e);
// return new ToolExecuteResult("Error: " + e.getMessage());
// }
// }

// /**
// * List uploaded files - jmanus style: simple and direct
// */
// private ToolExecuteResult listUploadedFiles() throws IOException {
// List<String> fileList = new ArrayList<>();

// // 1. Prioritize checking current plan files (directly in plan directory)
// Path currentPlanDir = directoryManager.getRootPlanDirectory(currentPlanId);
// if (Files.exists(currentPlanDir)) {
// addFilesFromDirectory(currentPlanDir, fileList);
// }

// // 2. If current plan has files, prioritize using current plan files
// if (!fileList.isEmpty()) {
// log.info("Using files from current plan only: {}", currentPlanId);
// }
// else {
// log.info("No files in current plan, recommending upload to current plan...");
// return new ToolExecuteResult("""
// ❌ No uploaded files found in current plan

// 🎯 **Suggested Solution**:
// 1. Please upload files to be analyzed in the current plan
// 2. This avoids file ownership confusion
// 3. Ensures analysis of correct and latest files

// 💡 **Why do this**:
// - Files and analysis in the same plan, clearer logic
// - Avoid processing irrelevant historical files
// - Improve system performance and accuracy

// 📁 Please upload files and then re-execute the analysis task.
// """);
// }

// StringBuilder result = new StringBuilder("📁 Available uploaded files:\n\n");
// for (int i = 0; i < fileList.size(); i++) {
// result.append(String.format("%d. %s\n", i + 1, fileList.get(i)));
// }

// // Extract pure file name list for convenient agent use
// result.append("\n📋 File names for processing:\n");
// for (String fileInfo : fileList) {
// String fileName = extractFileName(fileInfo);
// result.append(" - " + fileName + "\n");
// }

// result.append("\n💡 **Next Step Guide**:\n");
// result.append(" - To process file: {\"action\": \"process_file\", \"file_name\":
// \"exact_file_name\"}\n");
// result.append(" - ⚠️ **Important**: Don't call list_files repeatedly, all available
// files are shown\n");
// result
// .append(" - 📋 Suggestion: After processing needed files, use terminate tool to
// complete task summary\n");
// result.append("\n📋 Supported file types: All common file types are automatically
// detected and processed");

// log.info("Listed {} files for planId: {}", fileList.size(), currentPlanId);
// return new ToolExecuteResult(result.toString());
// }

// /**
// * Process specified file - Smart tool selection (jmanus style)
// */
// private ToolExecuteResult processFile(UploadedFileInput input) {
// String fileName = input.getFileName();
// if (fileName == null || fileName.trim().isEmpty()) {
// return new ToolExecuteResult("❌ Error: file_name is required for process_file action");
// }

// // 1. Find file and location information
// FileLocation fileLocation = findUploadedFileLocation(fileName);
// if (fileLocation == null || !Files.exists(fileLocation.filePath)) {
// return new ToolExecuteResult(
// "❌ File not found: " + fileName + ". Use 'list_files' action to see available files.");
// }

// // 2. Smart tool selection (jmanus approach: function-based intelligence)
// String extension = getFileExtension(fileName);
// if (extension.isEmpty()) {
// return new ToolExecuteResult("❌ File has no extension: " + fileName + ". Cannot
// determine file type.");
// }

// // Log processing information
// log.info("Processing file: {} (type: {}) from plan: {}", fileName, extension,
// fileLocation.planId);

// // 3. Smart tool selection based on file type (the real "function as first-class
// // citizen")
// return selectAndExecuteTool(fileLocation, extension);
// }

// /**
// * Smart tool selection - Function as first-class citizen concept Each file type maps
// * to a processing function
// */
// private ToolExecuteResult selectAndExecuteTool(FileLocation fileLocation, String
// extension) {
// String ext = extension.toLowerCase().substring(1);

// // Function-based dispatch - each case represents a "processing function"
// return switch (ext) {
// case "pdf" -> processPdf(fileLocation);
// case "xlsx", "xls" -> processExcel(fileLocation, ext);
// case "csv" -> processCsv(fileLocation);
// case "txt", "md", "json", "xml", "yaml", "yml", "log", "java", "py", "js", "html",
// "css" ->
// processText(fileLocation);
// case "tsv" -> processTable(fileLocation);
// default -> processFallback(fileLocation);
// };
// }

// // ===== Processing Functions (jmanus style: simple tool creation) =====

// /**
// * Process PDF files
// */
// private ToolExecuteResult processPdf(FileLocation fileLocation) {
// throw new UnsupportedOperationException("PDF processing is not supported");
// }

// /**
// * Process Excel files with enhanced structure + data reading
// */
// private ToolExecuteResult processExcel(FileLocation fileLocation, String ext) {
// try {
// IExcelProcessingService excelService =
// applicationContext.getBean(IExcelProcessingService.class);

// // Step 1: Get Excel structure
// ExcelProcessorTool structureTool = new ExcelProcessorTool(excelService);
// ExcelProcessorTool.ExcelInput structureInput = new ExcelProcessorTool.ExcelInput();
// structureInput.setAction("get_structure");
// structureInput.setFilePath(fileLocation.filePath.toString());

// structureTool.setCurrentPlanId(fileLocation.planId);
// structureTool.setRootPlanId(fileLocation.planId);

// ToolExecuteResult structureResult = structureTool.run(structureInput);

// // Step 2: Try to read data from default worksheet
// if (structureResult != null && structureResult.getOutput().contains("worksheets")) {
// try {
// ExcelProcessorTool dataTool = new ExcelProcessorTool(excelService);
// ExcelProcessorTool.ExcelInput dataInput = new ExcelProcessorTool.ExcelInput();
// dataInput.setAction("read_data");
// dataInput.setFilePath(fileLocation.filePath.toString());
// dataInput.setWorksheetName("Sheet1");

// dataTool.setCurrentPlanId(fileLocation.planId);
// dataTool.setRootPlanId(fileLocation.planId);

// ToolExecuteResult dataResult = dataTool.run(dataInput);

// // Combine structure and data
// if (dataResult != null && !dataResult.getOutput().contains("Error")) {
// return new ToolExecuteResult(
// structureResult.getOutput() + "\n\n📊 Data from Sheet1:\n" + dataResult.getOutput());
// }
// }
// catch (Exception dataEx) {
// log.debug("Could not read default worksheet, returning structure only: {}",
// dataEx.getMessage());
// }
// }

// log.info("✅ Processing with ExcelProcessorTool: {}",
// fileLocation.filePath.getFileName());
// return structureResult;
// }
// catch (Exception e) {
// log.warn("ExcelProcessorTool failed: {}", e.getMessage());
// return new ToolExecuteResult("❌ Excel processing error: " + e.getMessage());
// }
// }

// /**
// * Process CSV files
// */
// private ToolExecuteResult processCsv(FileLocation fileLocation) {
// try {
// IExcelProcessingService excelService =
// applicationContext.getBean(IExcelProcessingService.class);

// ExcelProcessorTool excelTool = new ExcelProcessorTool(excelService);
// ExcelProcessorTool.ExcelInput excelInput = new ExcelProcessorTool.ExcelInput();
// excelInput.setAction("read_csv");
// excelInput.setFilePath(fileLocation.filePath.toString());

// excelTool.setCurrentPlanId(fileLocation.planId);
// excelTool.setRootPlanId(fileLocation.planId);

// log.info("✅ Processing with ExcelProcessorTool (CSV): {}",
// fileLocation.filePath.getFileName());
// return excelTool.run(excelInput);
// }
// catch (Exception e) {
// log.warn("CSV processing failed: {}", e.getMessage());
// return new ToolExecuteResult("❌ CSV processing error: " + e.getMessage());
// }
// }

// /**
// * Process text files
// */
// private ToolExecuteResult processText(FileLocation fileLocation) {
// try {
// TextFileService textService = applicationContext.getBean(TextFileService.class);
// SmartContentSavingService storageService =
// applicationContext.getBean(SmartContentSavingService.class);
// ObjectMapper objectMapper = applicationContext.getBean(ObjectMapper.class);

// GlobalFileOperator textOperator = new GlobalFileOperator(textService, storageService,
// objectMapper);
// GlobalFileOperator.GlobalFileInput textInput = new
// GlobalFileOperator.GlobalFileInput();
// textInput.setAction("get_all_text");
// textInput.setFilePath(fileLocation.filePath.toString());

// textOperator.setCurrentPlanId(fileLocation.planId);
// textOperator.setRootPlanId(fileLocation.planId);

// log.info("✅ Processing with TextFileOperator: {}",
// fileLocation.filePath.getFileName());
// return textOperator.run(textInput);
// }
// catch (Exception e) {
// log.warn("Text processing failed: {}", e.getMessage());
// return new ToolExecuteResult("❌ Text processing error: " + e.getMessage());
// }
// }

// /**
// * Process table files
// */
// private ToolExecuteResult processTable(FileLocation fileLocation) {
// try {
// TableProcessingService tableService =
// applicationContext.getBean(TableProcessingService.class);

// TableProcessorTool tableTool = new TableProcessorTool(tableService);
// TableProcessorTool.TableInput tableInput = new TableProcessorTool.TableInput();
// tableInput.setAction("read_table");
// tableInput.setFilePath(fileLocation.filePath.toString());

// tableTool.setCurrentPlanId(fileLocation.planId);
// tableTool.setRootPlanId(fileLocation.planId);

// log.info("✅ Processing with TableProcessorTool: {}",
// fileLocation.filePath.getFileName());
// return tableTool.run(tableInput);
// }
// catch (Exception e) {
// log.warn("Table processing failed: {}", e.getMessage());
// return new ToolExecuteResult("❌ Table processing error: " + e.getMessage());
// }
// }

// /**
// * Fallback processing: simple text reading
// */
// private ToolExecuteResult processFallback(FileLocation fileLocation) {
// try {
// String content = Files.readString(fileLocation.filePath);
// log.info("✅ Fallback text reading: {}", fileLocation.filePath.getFileName());
// return new ToolExecuteResult("File content (from plan " + fileLocation.planId + "):\n"
// + content);
// }
// catch (Exception e) {
// log.error("All processing methods failed for file: {}",
// fileLocation.filePath.getFileName());
// return new ToolExecuteResult("❌ Unable to process file: " + e.getMessage());
// }
// }

// // ===== Helper Methods (jmanus style: simple utilities) =====

// private void addFilesFromDirectory(Path uploadDir, List<String> fileList) throws
// IOException {
// Files.list(uploadDir).filter(Files::isRegularFile).forEach(filePath -> {
// try {
// String fileName = filePath.getFileName().toString();
// long size = Files.size(filePath);
// String sizeStr = formatFileSize(size);
// fileList.add(String.format("%s (%s)", fileName, sizeStr));
// log.info("Found file: {} ({})", fileName, sizeStr);
// }
// catch (IOException e) {
// log.warn("Error reading file info: {}", filePath, e);
// }
// });
// }

// private String extractFileName(String fileInfo) {
// try {
// int sizeIndex = fileInfo.indexOf(" (");
// return sizeIndex > 0 ? fileInfo.substring(0, sizeIndex) : fileInfo;
// }
// catch (Exception e) {
// log.warn("Error extracting filename from: {}", fileInfo, e);
// return fileInfo;
// }
// }

// private String formatFileSize(long size) {
// if (size < 1024)
// return size + " B";
// else if (size < 1024 * 1024)
// return String.format("%.1f KB", size / 1024.0);
// else
// return String.format("%.1f MB", size / (1024.0 * 1024.0));
// }

// private String getFileExtension(String fileName) {
// int lastDotIndex = fileName.lastIndexOf('.');
// return lastDotIndex > 0 ? fileName.substring(lastDotIndex) : "";
// }

// /**
// * Simple file location data class - jmanus style
// */
// private static class FileLocation {

// final Path filePath;

// final String planId;

// FileLocation(Path filePath, String planId, boolean isCurrentPlan) {
// this.filePath = filePath;
// this.planId = planId;
// }

// }

// /**
// * Find uploaded file location
// */
// private FileLocation findUploadedFileLocation(String fileName) {
// // 1. Check current plan (directly in plan directory)
// Path currentFile =
// directoryManager.getRootPlanDirectory(currentPlanId).resolve(fileName);

// if (Files.exists(currentFile)) {
// log.info("Found file in current plan: {}", fileName);
// return new FileLocation(currentFile, currentPlanId, true);
// }

// // 2. Check recent plans
// try {
// Path innerStorageRoot = directoryManager.getInnerStorageRoot();
// if (!Files.exists(innerStorageRoot)) {
// return null;
// }

// List<Path> recentPlans = Files.list(innerStorageRoot)
// .filter(Files::isDirectory)
// .filter(path -> path.getFileName().toString().startsWith("plan-"))
// .filter(path -> !path.getFileName().toString().equals(currentPlanId))
// .sorted((p1, p2) -> {
// try {
// return Files.getLastModifiedTime(p2).compareTo(Files.getLastModifiedTime(p1));
// }
// catch (IOException e) {
// return 0;
// }
// })
// .limit(10)
// .toList();

// for (Path planDir : recentPlans) {
// Path candidate = planDir.resolve(fileName);
// if (Files.exists(candidate)) {
// String planId = planDir.getFileName().toString();
// log.info("Found file {} in recent plan: {}", fileName, planId);
// return new FileLocation(candidate, planId, false);
// }
// }
// }
// catch (IOException e) {
// log.warn("Error searching recent plans", e);
// }

// return null;
// }

// // ===== Tool Interface Implementation =====

// @Override
// public String getName() {
// return TOOL_NAME;
// }

// @Override
// public String getDescription() {
// return "Intelligent file processing tool - Automatically recognizes and processes
// various file types. "
// + "Workflow: 1.Use list_files to view available files (only call once) "
// + "2.Use process_file to process needed files one by one "
// + "3.After processing all files use other tools to complete final task. "
// + "Important: list_files only needs to be called once, don't call repeatedly, "
// + "if needed files are processed should proceed to next step. "
// + "Best practice: Upload and analyze files in current plan, prioritize processing files
// in current plan. "
// + "Supported file types: PDF documents automatic text extraction, Excel/CSV automatic
// data reading, "
// + "text files automatic content reading, other formats intelligent selection
// processing. "
// + "Note: Prioritize using files in current plan to ensure analyzing most relevant
// content.";
// }

// @Override
// public String getParameters() {
// return "{\"type\":\"object\"," + "\"properties\":{" +
// "\"action\":{\"type\":\"string\","
// + "\"description\":\"Operation type: list_files (list files) or process_file
// (intelligent file processing)\","
// + "\"enum\":[\"list_files\",\"process_file\"]}," +
// "\"file_name\":{\"type\":\"string\","
// + "\"description\":\"Filename to process (required for process_file). Must be the exact
// filename shown in list_files results\"}"
// + "}," + "\"required\":[\"action\"]}";
// }

// @Override
// public Class<UploadedFileInput> getInputType() {
// return UploadedFileInput.class;
// }

// @Override
// public void cleanup(String planId) {
// // File processing tool doesn't need special cleanup logic
// log.info("UploadedFileLoaderTool cleanup for planId: {}", planId);
// }

// @Override
// public String getCurrentToolStateString() {
// return String.format(
// "UploadedFileLoaderTool State:\n- Current Plan ID: %s\n- Supported File Types: pdf,
// xlsx, xls, csv, txt, md, json, xml, yaml, yml, log, java, py, js, html, css",
// currentPlanId);
// }

// @Override
// public String getServiceGroup() {
// return "default-service-group";
// }

// @Override
// public boolean isSelectable() {
// return true;
// }

// }
